﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using System.IO;

namespace GenIX
{
    public partial class MainForm : Form
    {
        // <BaseMetods>
        // ======================= Базовые методы ===================================
        //</BaseMetods>

        //<numberChildNode>
        //Подсчет количества дочерних узлов
        //</numberChildNode>
        private int Number(string filename)
        {
            int number = 0;

            foreach (XmlNode table in xmlDoc.DocumentElement.ChildNodes)
            {
                foreach (XmlNode ch in table.ChildNodes)
                {
                    number++;
                }
            }

            return number;
        }


        //<buildTree>
        // Построение иерархического дерева файла
        //</buildTree>
        private void buildTree(string filename)
        {
            try
            {
                //<loadXml> 
                //Загружаем XML-документ из файла 
                //</loadXml>
                xmlDoc.Load(filename);

                hierarchyTreeView.Nodes.Clear();
                TreeNode tnode = hierarchyTreeView.Nodes.Add(filename);

                foreach (XmlNode table in xmlDoc.DocumentElement.ChildNodes)
                {
                    tnode.Nodes.Add("[" + table.ChildNodes[0].InnerText + "] " +
                    table.ChildNodes[1].InnerText + ": '" +
                    table.ChildNodes[2].InnerText + "'");

                    // <tableChildNodes> перебираем всех детей текущего узла </tableChildNodes>
                    foreach (XmlNode ch in table.ChildNodes)
                    {

                    }
                }
                hierarchyTreeView.ExpandAll();

            }

            // <XmlException> Перехват сообщения об исключениях XML </XmlException>
            catch (XmlException e)
            {
                MessageBox.Show(e.Message, "Ошибка корректности файла XML", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // <NullReferenceException> Перехват сообщения об исключениях отсутствия указателя на объект </NullReferenceException>
            catch (NullReferenceException e)
            {
                MessageBox.Show(e.Message, "Объект не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // <FileNotFoundException> Перехват сообщения об исключениях отсутствия файла </FileNotFoundException>
            catch (System.IO.FileNotFoundException e)
            {
                MessageBox.Show(e.Message, "Файл DTD схемы не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // <ArgumentException> Перехват сообщения об исключениях отсутствия файла </ArgumentException>
            catch (ArgumentException e)
            {
                MessageBox.Show(e.Message, "Неверный аргумент", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // <FormatException> Перехват сообщения об исключениях неверного формата даты </FormatException>
            catch (FormatException e)
            {
                MessageBox.Show(e.Message, "Неверный формат даты", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // <UnauthorizedAccessException> Перехват сообщения об исключениях доступа к файлу </UnauthorizedAccessException>
            catch (UnauthorizedAccessException e)
            {
                MessageBox.Show(e.Message, "Доступ к файлу запрещен", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        // <ParsingXml>
        // Парсинг (синтаксический анализ) файла XML и построение интерфейса
        // </ParsingXml>
        private bool Parsing(string filename, bool edit, int number_node)
        {
            int i = 0, y = 10;
            string AppPath = string.Empty;
            string DTDFile = string.Empty;
            string XmlDTDFile = string.Empty;

            try
            {
                if (!Valid.Enabled)
                    Validating(filename);

                // <ifValid> Если валиден </ifValid>
                if (isValid)
                {                     
                    AppPath = Application.ExecutablePath;
                    DTDFile = Path.GetDirectoryName(AppPath) + "\\DTD\\ROWS.dtd";
                    XmlDTDFile = Path.GetDirectoryName(filename) + "\\ROWS.dtd";

                    if (File.Exists(DTDFile))
                    {
                        FileInfo FI = new FileInfo(DTDFile);
                        if (!File.Exists(XmlDTDFile))
                        {
                            FI.CopyTo(XmlDTDFile, false);
                            CheckWrite[lenghtWrite] = XmlDTDFile;
                            lenghtWrite++;
                        }
                    }
                    
                    // <LoadXml> Загружаем XML-документ из файла </LoadXml>
                    xmlDoc.Load(filename);

                    interfacePanel.Controls.Clear();

                    // <CreateElement> Создание массивов элементов управления </CreateElement>
                    TxtB = new TextBox[Number(filename)];
                    Lbl = new Label[Number(filename)];

                    XmlNode table = xmlDoc.DocumentElement.ChildNodes[number_node];

                    // <ChildNodes> перебираем всех детей текущего узла </ChildNodes>
                    foreach (XmlNode ch in table.ChildNodes)
                    {
                        textboxText = ch.InnerText;
                        
                        // <ifDefault> Если стандартное поле </ifDefault> 
                        switch (ch.Name)
                        {
                            case "TASK_ID": labelText = "Номер задания";  CreateTextBox(i, false, y); break;

                            case "ASSIGN_TO": labelText = "Назначено"; CreateComboBox(i, edit, y, ComboAssignPerson, false); break;

                            case "TASK_NAME": labelText = "Название"; CreateTextBox(i, edit, y); break;

                            case "DEADLINE": labelText = "Крайний срок"; CreateDateTimePicker(i, edit, y, "dd.MM.yyyy"); break;

                            case "STATUS": labelText = "Статус"; CreateComboBox(i, edit, y, ComboStatus, true); break;

                            case "IMPORTNANCE": labelText = "Важность"; CreateComboBox(i, edit, y, ComboImportnance, true); break;

                            case "URGENCY": labelText = "Срочность"; CreateComboBox(i, edit, y, ComboUrgency, true); break;

                            case "CREATED_DATE": labelText = "Создано"; CreateDateTimePicker(i, false, y, "dd.MM.yyyy HH:mm"); break;

                            case "LAST_UPDATE": labelText = "Последнее обновление"; CreateDateTimePicker(i, false, y, "dd.MM.yyyy HH:mm"); break;

                            case "CREATEDBY_USER": labelText = "Кем создано"; CreateTextBox(i, false, y); break;

                            case "UPDATEDBY_USER": labelText = "Кем обновлено"; CreateTextBox(i, false, y); break;

                            case "PROGRESS": labelText = "Степень выполнения"; CreateComboBox(i, edit, y, ComboProgress, true); break;

                            case "ACTUAL_END": labelText = "Завершено"; CreateDateTimePicker(i, edit, y, "dd.MM.yyyy"); break;

                            
                            default: labelText = ch.Name; CreateTextBox(i, edit, y); break;
                        }

                        i++;
                        y += 30;
                    }
                    Styleform.SelectElement(this, Styleform.choseStyleName);
					
                    
                    return true;
                }
                // <ifNotValid> Если валиден </ifNotValid>
                else
                {
                    return false;
                }
            }

            // <XmlException> Перехват сообщения об исключениях XML </XmlException>
            catch (XmlException e)
            {
                MessageBox.Show(e.Message, "Ошибка корректности файла XML", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            // <NullReferenceException> Перехват сообщения об исключениях отсутствия указателя на объект </NullReferenceException>
            catch (NullReferenceException e)
            {
                MessageBox.Show(e.Message, "Объект не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            // <FileNotFoundException> Перехват сообщения об исключениях отсутствия файла </FileNotFoundException>
            catch (System.IO.FileNotFoundException)
            {
                DTDFile = Path.GetDirectoryName(AppPath) + "\\DTD\\ROWS.dtd";
                MessageBox.Show("Файл DTD схемы " + DTDFile + " не найден", "Файл DTD схемы не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            // <ArgumentException> Перехват сообщения об исключениях отсутствия файла </ArgumentException>
            catch (ArgumentException e)
            {
                MessageBox.Show(e.Message, "Неверный аргумент", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            // <UnauthorizedAccessException> Перехват сообщения об исключениях доступа к файлу </UnauthorizedAccessException>
            catch (UnauthorizedAccessException e)
            {
                MessageBox.Show(e.Message, "Доступ к файлу запрещен", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }


        // <saveNode>
        // Сохранение текущего узла дерева
        // </saveNode>
        private void saveNode(string filename, int number_node)
        {
            int i = 0;

            XmlNode table = xmlDoc.DocumentElement.ChildNodes[number_node];

            // Изменения значений дочерних узлов
            foreach (XmlNode ch in table.ChildNodes)
            {

                switch (ch.Name)
                {
                    case "ASSIGN_TO": ch.InnerText = CmbB[i].Text; break;

                    case "DEADLINE": ch.InnerText = DTP[i].Text; break;

                    case "STATUS": ch.InnerText = CmbB[i].Text; break;

                    case "IMPORTNANCE": ch.InnerText = CmbB[i].Text; break;

                    case "URGENCY": ch.InnerText = CmbB[i].Text; break;

                    case "LAST_UPDATE": DTP[i].Text = DateTime.Now.ToString(); ch.InnerText = DTP[i].Text; break;

                    case "CREATED_DATE": ch.InnerText = DTP[i].Text; break;

                    case "UPDATEDBY_USER": ch.InnerText = tbCurUser.Text; break;

                    case "PROGRESS": ch.InnerText = CmbB[i].Text; break;

                    case "ACTUAL_END": ch.InnerText = DTP[i].Text; break;

                    default: ch.InnerText = TxtB[i].Text; break;
                }

                i++;
            }

            try
            {
                // <SaveFile> Сохранение файла </SaveFile>
                xmlDoc.Save(filename);
                if (hierarchyTreeView.SelectedNode != null)
                    Parsing(filename, false, hierarchyTreeView.SelectedNode.Index);
                else
                    Parsing(filename, false, 0);
                saveToolStripMenuItem.Enabled = false;
            }

            // <XmlException> Перехват сообщения об исключениях XML </XmlException>
            catch (XmlException e)
            {
                MessageBox.Show(e.Message, "Ошибка корректности файла XML", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // <NullReferenceException> Перехват сообщения об исключениях отсутствия указателя на объект </NullReferenceException>
            catch (NullReferenceException e)
            {
                MessageBox.Show(e.Message, "Объект не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // <FileNotFoundException> Перехват сообщения об исключениях отсутствия файла </FileNotFoundException>
            catch (System.IO.FileNotFoundException e)
            {
                MessageBox.Show(e.Message, "Файл DTD схемы не найден", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // <ArgumentException> Перехват сообщения об исключениях отсутствия файла </ArgumentException>
            catch (ArgumentException e)
            {
                MessageBox.Show(e.Message, "Неверный аргумент", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // <UnauthorizedAccessException> Перехват сообщения об исключениях доступа к файлу </UnauthorizedAccessException>
            catch (UnauthorizedAccessException e)
            {
                MessageBox.Show(e.Message, "Доступ к файлу запрещен", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }


        // <Validating> 
        // Проверка валидности XML документа
        // </Validating>
        private void Validating(string filename)
        {
            isValid = true;

            XmlTextReader r = new XmlTextReader(filename);
            XmlValidatingReader vReader = new XmlValidatingReader(r);

            vReader.ValidationType = ValidationType.DTD;

            vReader.ValidationEventHandler +=
            new ValidationEventHandler(MyValidationEventHandler);


            while (vReader.Read())
            {
                //
            }
            vReader.Close();

            // <Valid> Проверка валидности </Valid>
            if (isValid)
                validMessage = "";
            else
                MessageBox.Show(validMessage, "Ошибка в схеме файла XML", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }


        public void MyValidationEventHandler(object sender,

                                           ValidationEventArgs args)
        {
            isValid = false;
            validMessage = args.Message;
        }

        // <ChangeUser>
        // Смена пользователя
        // </ChangeUser>
        public void ChangeUser(string UserName)
        {
            if (tbCurUser.Text != UserName)
                tbCurUser.Text = UserName;
            Authorized = true;
        }
        
    }
}